package com.huwaiwai001.queue;

import java.util.Arrays;
import java.util.Objects;

/**
 * Created by hww on 2019/1/3 3:11 PM.
 */
public class MyABQ<T> implements ABQ<T> {

    private Object[] element;

    private int takeIndex = 0;

    private int putIndex = 0;

    private int size = 0;

    MyABQ(int capacity) {
        this.element = new Object[capacity];
    }

    /**
     * 计算下一次的下标
     */
    private int add(int index) {
        return index == element.length - 1 ? 0 : ++index;
    }

    @Override
    public T get() {
        if (size <= 0) {
            return null;
        }
        //1.获取当前位置值
        Object e = element[takeIndex];
        element[takeIndex] = null;
        //2.变更提取元素的下标
        takeIndex = add(takeIndex);
        //3.删除元素，减少计数
        size--;
        //4.返回元素
        return (T)e;
    }

    @Override
    public boolean put(T e) {
        if (size == element.length) {
            return false;
        }
        //1.设置当前值到放入位
        element[putIndex] = e;
        //2.变更插入元素下标
        putIndex = add(putIndex);
        //3.增加计数
        size++;
        return true;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean contains(T e) {
        for (int i = takeIndex; i != putIndex; i = add(i)) {
            if (Objects.equals(e, element[i])) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean remove(T e) {
        if (size <= 0) {
            return false;
        }
        if (Objects.equals(e, element[takeIndex])) {
            element[takeIndex] = null;
            takeIndex = add(takeIndex);
            size--;
        }
        boolean hasElement = false;
        for (int i = takeIndex; i != putIndex; i = add(i)) {
            if (hasElement || Objects.equals(e, element[i])) {
                element[i] = element[add(i)];
                hasElement = true;
            }
        }
        if (hasElement) {
            if (putIndex == 0) {
                putIndex = element.length - 1;
            } else {
                putIndex--;
            }
        }
        return hasElement;
    }

    @Override
    public String toString() {
        return Arrays.toString(element);
    }
}
